package com.ccl.iot;import com.ccl.iot.privates.ListMap;
import com.ccl.iot.IOTInfoMonitor.IOTInfoListener;
import com.ccl.iot.IOTInterface.IOTStructureMonitorInterface.IOTMemberValueChangeListener;
import com.ccl.iot.object.IOTInfoWithValue;

public class IOTStructInfoMonitor implements IOTObject{
	public interface IOTStructureInfoSource extends IOTStructureArray{
		public String getMemberLabel(IOTObject aDemander, long aIndex, String aMember);
		public String getMemberName(IOTObject aDemander, long aIndex, String aMemberLabel);
	}
	
	
	private IOTInfoSynchro iInfoSynchro = null;
	private IOTStructureInfoSource iMonitorSource = null;
	
	private ListMap<IOTInfoListener, IOTMemberValueChangeListener> iMemberValueChangedListener = null;
	
	
	IOTStructInfoMonitor(IOTInfoSynchro aInfoSynchro, IOTStructureInfoSource aMonitorSource){
		iInfoSynchro = aInfoSynchro;
		iMonitorSource = aMonitorSource;
	}

	@Override
	public long getID() {
		return this.hashCode();
	}
	
	public boolean addMemberChangeListener(long aIndex, String aMember, IOTMemberValueChangeListener aListener) {
		if (iInfoSynchro != null && iMonitorSource != null){
			if (iMemberValueChangedListener == null){
				iMemberValueChangedListener = new ListMap<IOTInfoListener, IOTMemberValueChangeListener>();
			}
			
			IOTInfoListener tListener = new IOTInfoMonitor.IOTInfoListener() {
				private IOTMemberValueChangeListener getMemberValueChangeListener(){
					if (iMemberValueChangedListener != null){
						return iMemberValueChangedListener.getValue(this);
					}
					
					return null;
				}
				
				private void onValueChanged(String aMember, String aValue){
					IOTMemberValueChangeListener tListener;
					
					if ((tListener = getMemberValueChangeListener()) != null){
						tListener.onMemberValueChanged(iMonitorSource, aMember, aValue);
					}
				}
				
				@Override
				public void onNewInfo(IOTInfoWithValue aInfo) {
					onValueChanged(aInfo.getName(), aInfo.getValue());
				}
				
				@Override
				public void onInfoChanged(IOTInfoWithValue aInfo) {
					onValueChanged(aInfo.getName(), aInfo.getValue());
				}
				
				@Override
				public void onInfoRemoved(IOTInfoWithValue aInfo) {
					onValueChanged(aInfo.getName(), IOTNamedObject.KIOT_DEFAULT_NAME);
				}
			};
			
			if (iInfoSynchro.addInfoListener(iMonitorSource.getMemberLabel(this, aIndex, aMember), tListener)){
				if (iMemberValueChangedListener.add(tListener, aListener)){
					return true;
				}else{
					iInfoSynchro.removeInfoListener(tListener);
				}
			}
		}
		
		return false;
	}

	public boolean addMemberChangeListener(String aMember, IOTMemberValueChangeListener aListener) {
		return addMemberChangeListener(0, aMember, aListener);
	}
	
	public boolean removeMemberChangeListener(IOTMemberValueChangeListener aListener){
		if (iMemberValueChangedListener != null && aListener != null){
			boolean tRet = false;
			IOTInfoListener tListener;
			
			while((tListener = iMemberValueChangedListener.getKey(aListener)) != null){
				if (iMemberValueChangedListener.remove(tListener)){
					tRet  = true;
					
					if (iInfoSynchro != null){
						iInfoSynchro.removeInfoListener(tListener);
					}
				}else{
					break;
				}
			}

			return tRet;
		}
		
		return false;
	}
}
